%%%-------------------------------------------------------------------
%%% File    : p33.erl
%%% Author  :  <>
%%% Description : 
%%% The fraction ^(49)/_(98) is a curious fraction, as an 
%%% inexperienced mathematician in attempting to simplify it may 
%%% incorrectly believe that ^(49)/_(98) = ^(4)/_(8), which is correct, 
%%% is obtained by cancelling the 9s.
%%%
%%% We shall consider fractions like, ^(30)/_(50) = ^(3)/_(5), to be 
%%% trivial examples.
%%%
%%% There are exactly four non-trivial examples of this type of fraction, 
%%% less than one in value, and containing two digits in the numerator 
%%% and denominator.
%%%
%%% If the product of these four fractions is given in its lowest common 
%%% terms, find the value of the denominator.
%%%
%%% Created : 27 Dec 2008 by  <>
%%%-------------------------------------------------------------------
-module(p33).

%% API
-compile(export_all).

% All the possible 2 digit fractions are generated from simple 1 digit 
% ones where the denominator is greater than the nominator:
% 1/2, 1/3 ...1/9, 2/3....8/9
% The solution -> for all possible one digit fractions, generate all
% possible two digit ones where the same digit is appended to both the
% nominator and the denominator, but not necessarily at the same side:
% 1/2 -> 13/23, 13/32, 31/23, 31/32
% Iterating through all such fractions we calculate the products of
% the nominator and the denominator. I didn't bother simplifying
% the result and just did it in my head, but it is trivial anyway. 
%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: 
%% Description:
%%--------------------------------------------------------------------
solution()->
    lists:foldl(fun(X, Acc) -> test_one(X, denominators(X), 1, Acc) end, {1, 1}, lists:seq(1, 8)).
%%====================================================================
%% Internal functions
%%====================================================================
test_one(_, _, TestN, Acc) when TestN > 9 ->
    Acc;
test_one(X, [], TestN, Acc) ->
    test_one(X, denominators(X), TestN+1, Acc);
test_one(X, [H|Denominators], TestN, {AccN, AccD} = Acc ) ->
    N1 = X*10 + TestN,
    N2 = X + TestN*10,
    D1 = H*10 + TestN,
    D2 = H + TestN*10,
    Simple = X / H,
    case N1/D1 =:= Simple orelse N1/D2 =:= Simple orelse N2/D1 =:= Simple orelse N2/D2 =:= Simple of
        true -> 
            test_one(X, Denominators, TestN, {X*AccN, H*AccD});
        _ ->
            test_one(X, Denominators, TestN, Acc)
    end.
                                     
denominators(X) when X > 0 andalso X < 9 ->
    [J || J <- lists:seq(X+1, 9)].
